//
//  SQLiteDataBaseManger.m
//  18-SQLite
//
//  Created by dllo on 16/8/8.
//  Copyright © 2016年 DM.C. All rights reserved.
//

#import "SQLiteDataBaseManger.h"
#import "Student.h"
@implementation SQLiteDataBaseManger
#pragma mark - 单例创建方式, 只有一个对象
// 内存管理中, 单例不能被释放
+ (SQLiteDataBaseManger *)sharedManager {
    static SQLiteDataBaseManger *manager = nil;
    // 保证线程安全的情况下, 只执行一次
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[SQLiteDataBaseManger alloc] init];
    });
    return manager;
}
- (BOOL)openSQLite3 {
    NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *douctment = [pathArray firstObject];
    // 数据库SQLite3文件类型  .db
    NSString *dbPath = [douctment stringByAppendingPathComponent:@"student.db"];
    NSLog(@"%@", dbPath);
    // UTF8String 属性 为将OC字符串转换成C语言字符串
    // 参数1: 数据库文件路径
    // 参数2: 指向指针的指针 该指针可以被修改 数据库管理指针
    int result = sqlite3_open([dbPath UTF8String], &dbPonint);
    return [self isOperationResult:result alertText:@"打开数据库"];
//    BOOL isOpen = YES;
//    // sqlite3_open 当路径文件不存在时, 文件会被SQLite创建并打开
//    // 当路径文件存在时, 文件被直接打开
//    // sqlite3_open 返回值为int类型, 0 SQLITE_OK代表成功 1 代表失败
//    if (result == SQLITE_OK) {
//        NSLog(@"数据库打开成功");
//        isOpen = YES;
//    } else {
//        NSLog(@"数据库打开失败-----%d", result);
//        isOpen = NO;
//    }
//    return isOpen;
}

- (BOOL)closeSQLite3 {
    // 关闭数据库时, 如果数据库处于打开状态, 则正常关闭, 显示成功
    // 如果数据库处于关闭状态, 则显示失败, 原因 21:库不存在
    int result = sqlite3_close(dbPonint);
    return [self isOperationResult:result alertText:@"关闭数据库"];
    
//    BOOL isClose = YES;
//    if (result == SQLITE_OK) {
//        NSLog(@"数据库关闭成功");
//        isClose = YES;
//    } else {
//        NSLog(@"数据库关闭失败-----%d", result);
//        isClose = NO;
//    }
//
//    sqlite3_close(dbPonint);
//    return isClose;
}

- (BOOL)createTable {
    // SQL语句
    // 创建表
    // create table 表名 (字段1 类型 约束 , 字段2..., 字段3...)
//    NSString *createSQL = @"create Table stu(stu_id integer primary key, stu_name text)";
    // 常用的约束
    // primary key 一个表, 有且只能有一个主键
    // autoincrement 自增, 添加完该字段, 系统会自己创建一个数据库
    // sqlite_sequence, 用来保存自增的值
    // not null 不能为空, 为空会报SQL错误
    
    // 删除表
    // drop table 表名
    NSString *createSQL = @"create Table stu2(stu_id integer primary key autoincrement, stu_name text not null)";

    int result = sqlite3_exec(dbPonint, [createSQL UTF8String], NULL, NULL, NULL);
    return [self isOperationResult:result alertText:@"创建表"];
}
- (BOOL)insertStu:(Student *)stu {
    NSString *insertSQL = [NSString stringWithFormat:@"insert into stu1 values (null, '%@')", stu.stu_name];
    // 自增字段, autoincrement
    // 默认如果填入null, 值会从1开始
    // 如果填入其他值, 会从其他值开始, 例: 填入110, 值会从110开始计算, 并进行存储
    // 存储在sqlite_sequence中
//    NSString *insertSQL = @"insert into stu2 values (null, '闪电')";
    int result = sqlite3_exec(dbPonint, [insertSQL UTF8String], NULL, NULL, NULL);
    return [self isOperationResult:result alertText:@"添加"];
}
- (BOOL)deleteStu:(Student *)stu {
    NSString *deleteSQL = [NSString stringWithFormat:@"delete from stu1 where stu_id=%ld", stu.stu_id];
    int result = sqlite3_exec(dbPonint, [deleteSQL UTF8String], NULL, NULL, NULL);
    NSString *alertText = [NSString stringWithFormat:@"删除学号为%ld的数据", stu.stu_id];
    return [self isOperationResult:result alertText:alertText];
}
- (BOOL)deleteAll {
    NSString *deleteSQL = @"delete from stu1 where 1=1";
    int result = sqlite3_exec(dbPonint, [deleteSQL UTF8String], NULL, NULL, NULL);
    return [self isOperationResult:result alertText:@"删除全部"];
}
- (BOOL)updateOldName:(NSString *)oldName
              newName:(NSString *)newName {
    // uodate 表名 set 字段名 = 新值 where 字段名 = 旧值
    NSString *updataSQL = [NSString stringWithFormat:@"update stu1 set stu_name = '%@' where stu_name = '%@'", newName, oldName];
    int result = sqlite3_exec(dbPonint, [updataSQL UTF8String], NULL, NULL, NULL);
    return [self isOperationResult:result alertText:@"更新数据"];
}
- (NSArray *)selectAll {
    // select 字段名, 字段名... from 表名 where 条件
    NSString *selectAll = @"select * from stu1";
    sqlite3_stmt *stmt = NULL;
    // 参数1: 数据库指针 sqlite3 *
    // 参数2: 数据库的SQL语句
    // 参数3: SQL语句的长度, -1
    // 参数4: 替身, 查询出的内容放入替身中, 并将替身反回
    // 参数5:
    int result = sqlite3_prepare(dbPonint, [selectAll UTF8String], -1, &stmt, NULL);
    NSMutableArray *stuArray = [NSMutableArray array];
    // 如果查询结果为成功
    if (result == SQLITE_OK) {
        // 循环遍历替身内容
        // step查询替身中有没有其他数据
        // 当包含有其他数据时, 结果为 SQLITE_ROW
        // 当不包含有其他数据时, 结果为 SQLITE_DONE
        while (sqlite3_step(stmt) == SQLITE_ROW) {
            // 循环体中, 取对应的每一列数据
            // 取出第0列的数据, 根据类型选择函数, text
            int stu_id = sqlite3_column_int(stmt, 0);
            // 取出第1列的数据, 根据类型选择函数, text
            const unsigned char *stu_name = sqlite3_column_text(stmt, 1);
            Student *stu = [[Student alloc] init];
            stu.stu_id = stu_id;
            stu.stu_name = [NSString stringWithUTF8String:(const char *)stu_name];
            [stuArray addObject:stu];
        }
    }
    // 循环结束后, 销毁替身
    sqlite3_finalize(stmt);
    return stuArray;
}




- (BOOL)isOperationResult:(int)result alertText:(NSString *)text {
    BOOL isOperation = YES;
    if (result == SQLITE_OK) {
        NSLog(@"%@成功" ,text);
        isOperation = YES;
    } else {
        NSLog(@"%@失败-----%d",text, result);
        isOperation = NO;
    }
    return isOperation;
}






@end
